package com.zmn.oms.admin.controller.work.modify;

import cn.hutool.core.bean.BeanUtil;
import com.google.common.collect.Lists;
import com.zmn.base.engineer.common.constants.DubboConsts;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerBasicInfoDRO;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.ccb.common.enums.CodeAndTextEnum;
import com.zmn.ccc.common.enums.ByeWayEnum;
import com.zmn.ccc.common.model.record.OrderRecordDRO;
import com.zmn.ccc.dubbo.interfaces.record.RecordRemoteService;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.admin.controller.OmsBaseController;
import com.zmn.oms.business.interfaces.callpop.CallRecordBService;
import com.zmn.oms.business.interfaces.xno.OrderTempXnoBindBService;
import com.zmn.oms.common.dio.redistribute.OrderWorkRedistributeApplyQuery;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.enums.WorkingRecordNodeEnum;
import com.zmn.oms.common.utils.MobileUtil;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.orderworkingrecord.OrderWorkingRecord;
import com.zmn.oms.model.entity.orderworkingrecord.OrderWorkingRecordQuery;
import com.zmn.oms.model.entity.redistribute.OrderWorkRedistributeApply;
import com.zmn.oms.model.vo.work.CallRecordVO;
import com.zmn.oms.model.vo.work.OrderWorkingRecordVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.orderworkingrecord.OrderWorkingRecordService;
import com.zmn.oms.services.interfaces.redistribute.OrderWorkRedistributeApplyService;
import com.zmn.track.dubbo.dio.apply.cancel.OrderCancelApplyQuery;
import com.zmn.track.dubbo.dro.apply.cancel.OrderCancelApplyDRO;
import com.zmn.track.dubbo.dto.TrackWorkDRO;
import com.zmn.track.dubbo.dto.TrackWorkQuery;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyListRemoteService;
import com.zmn.track.dubbo.interfaces.trackwork.TrackWorkListRemoteService;
import com.zmn.xno.dubbo.interfaces.call.CallRecordTapeFileDownloadRemoteService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 类描述：工单列表操作controller
 *
 * @author liuying
 * @date 2018/11/07 16:32
 */
@Controller
@RequestMapping("/work/modify")
public class WorkCallRecordController extends OmsBaseController {

    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderExtendService orderExtendService;
    @Autowired
    private CallRecordBService callRecordBService;
    @Resource
    private OrderTempXnoBindBService orderTempXnoBindBService;
    @Resource
    private OrderWorkingRecordService orderWorkingRecordService;
    @Resource
    private OrderWorkRedistributeApplyService orderWorkRedistributeApplyService;

    @Reference(version = com.zmn.xno.common.constant.SystemConstants.DUBBO_CONSTS_INTERFACE_VERSION, check = false)
    private CallRecordTapeFileDownloadRemoteService callRecordTapeFileDownloadRemoteService;

    @Reference(version = com.zmn.ccc.dubbo.interfaces.DubboConsts.INTERFACE_VERSION, check = false)
    private RecordRemoteService recordRemoteService;
    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private TrackWorkListRemoteService trackWorkListRemoteService;
    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyListRemoteService orderCancelApplyListRemoteService;

    @DubboReference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerListRemoteService engineerListRemoteService;

    /**
     * 录音
     */
    @RequestMapping(value = "/recording")
    @ResponseBody
    public ResultDTO recording(Long orderId, Long workId) {
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        return ResultDTO.success(orderDetail.getTelephone());
    }

    /**
     * 通话记录
     */
    @RequestMapping(value = "/callRecord")
    @ResponseBody
    public ModelAndView callRecord(Long orderId, Long workId) {

        ModelAndView mv = new ModelAndView("work/modify/callrecord");
        //   List<OrderCallRecord> orderCallRecords = orderCallRecordService.listOrderCallRecordByOrderId(orderId);
        // 小号通话记录
        List<CallRecordVO> callRecordVOList = callRecordBService.listXnoCallRecordByWorkId(workId);
        callRecordVOList.stream().forEach(callRecordVO -> {
            boolean tempXno = orderTempXnoBindBService.isTempXno(workId, callRecordVO.getBindId());
            if (tempXno) {
                callRecordVO.setType(6);
            }
        });
        // 查询录单呼叫ID
//        OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(workId);
//        if (Objects.nonNull(orderExtend) && !StringUtils.isBlank(orderExtend.getCallId())) {
//            CallRecordVO callRecordVO = callRecordBService.getCallRecordFromCCByCallRecordId(orderExtend.getCallId());
//            if (Objects.nonNull(callRecordVO)) {
//                callRecordVOList.add(callRecordVO);
//            }
//        }
//
//        // 查询订单呼叫记录
//        List<CallRecordVO> omsCallRecordVOS = callRecordBService.getCallRecordFromCCByOrderId("OMS", orderId);
//        if (CollectionUtils.isNotEmpty(omsCallRecordVOS)) {
//            callRecordVOList.addAll(omsCallRecordVOS);
//        }

        try {
            // 查询新CC通话记录
            List<CallRecordVO> cccRecordList = this.getCCCRecord(orderId, workId);
            if (CollectionUtils.isNotEmpty(cccRecordList)) {
                callRecordVOList.addAll(cccRecordList);
            }
        } catch (Exception ex) {
        }


        try {
            // 查询催单电话通话记录
            List<CallRecordVO> remindCallRecordVOS = callRecordBService.queryRemindRecords(orderId);
            callRecordVOList.addAll(remindCallRecordVOS);
        } catch (Exception ex) {
        }

        callRecordVOList.forEach(e -> {

            // 号码处理
            e.setCalledNo(MobileUtil.formatHideTel(e.getCalledNo()));
            e.setCallerNo(MobileUtil.formatHideTel(e.getCallerNo()));

            String typeName = "";
            switch (e.getType()) {
                case 1:
                    typeName = "普通通话";
                    break;
                case 2:
                    typeName = "小号通话";
                    break;
                case 3:
                    typeName = "IM通话";
                    break;
                case 4:
                    typeName = "呼叫通话";
                    break;
                case 5:
                    typeName = "机器人催单";
                    break;
                case 6:
                    typeName = "小号通话（临时小号)";
                    break;
                case 7:
                    typeName = String.format("机器人外呼-%s", e.getTypeName());
                    break;
                case 99:
                    typeName = "小号通话";
                    break;
            }
            e.setTypeName(typeName);
            if (e.getStatus() != null) {
                switch (e.getStatus()) {
                    case 1:
                        e.setConnect("否");
                        e.setAnswer("否");
                        break;
                    case 2:
                        e.setConnect("是");
                        e.setAnswer("否");
                        break;
                    case 3:
                        e.setConnect("是");
                        e.setAnswer("是");
                        break;
                }
            }
        });

        mv.addObject("callRecordList", callRecordVOList);

        // 工程师上门录音
        List<OrderWorkingRecord> orderWorkingRecords = orderWorkingRecordService.listByQuery(OrderWorkingRecordQuery.builder()
                .orderId(orderId)
                .workId(workId)
                .build());
        List<OrderWorkingRecordVO> collect = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(orderWorkingRecords)) {
            Set<Integer> engineerIds = orderWorkingRecords.stream().map(OrderWorkingRecord::getEngineerId)
                    .collect(Collectors.toSet());

            ResponseDTO<List<ForeignEngineerBasicInfoDRO>> listResponseDTO = engineerListRemoteService.listEngineerByIdSet(engineerIds);
            List<ForeignEngineerBasicInfoDRO> droList = listResponseDTO.getData();
            Map<Integer, ForeignEngineerBasicInfoDRO> droMap = droList.stream()
                    .collect(Collectors.toMap(ForeignEngineerBasicInfoDRO::getEngineerId, Function.identity()));
            collect = orderWorkingRecords.stream().map(orderWorkingRecord -> {
                OrderWorkingRecordVO orderWorkingRecordVO = BeanUtil.copyProperties(orderWorkingRecord, OrderWorkingRecordVO.class);
                orderWorkingRecordVO.setRecordStatusName(Objects.equals(orderWorkingRecord.getRecordStatus(), GlobalConsts.NO) ? "中断" : "完成");
                orderWorkingRecordVO.setRecordDurationStr(DateUtil.getDurationDesc(Long.valueOf(orderWorkingRecord.getRecordDuration())));
                orderWorkingRecordVO.setRecordNodeName(WorkingRecordNodeEnum.getNodeName(orderWorkingRecord.getRecordNode()));
                Integer detectionResult = orderWorkingRecord.getDetectionResult();
                if (Objects.equals(detectionResult, GlobalConsts.YES)) {
                    orderWorkingRecordVO.setDetectionResultStr("合格");
                } else if (Objects.equals(detectionResult, GlobalConsts.NO)) {
                    orderWorkingRecordVO.setDetectionResultStr("不合格");
                } else if (Objects.equals(detectionResult, GlobalConsts.NONE)) {
                    orderWorkingRecordVO.setDetectionResultStr("未知 - 未找到质检规则");
                } else {
                    orderWorkingRecordVO.setDetectionResultStr("");
                }
                ForeignEngineerBasicInfoDRO basicInfoDRO = droMap.get(orderWorkingRecord.getEngineerId());
                orderWorkingRecordVO.setEngineerNamePhone(basicInfoDRO.getRealName() + "-" + basicInfoDRO.getMaskMobile());
                return orderWorkingRecordVO;
            }).collect(Collectors.toList());
        }

        mv.addObject("workingRecordList", collect);
        return mv;
    }

    @GetMapping(value = "/callRecord/download/{finishTime}")
    @ResponseBody
    public ResultDTO downloadCallRecord(@PathVariable(name = "finishTime") String finishTime) {

        String start = finishTime.substring(0, 12);
        String end = LocalDateTime.parse(finishTime, DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).plusMinutes(1).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).substring(0, 12);
        callRecordTapeFileDownloadRemoteService.downloadAsync(start, end);

        return ResultDTO.success();
    }

    /**
     * 查询 新 cc 通话记录
     *
     * @param workId
     * @return
     */
    private List<CallRecordVO> getCCCRecord(Long orderId, Long workId) {

        List<Long> list = Lists.newArrayList(workId);
        // 需要加上所有跟单的ID
        TrackWorkQuery query = new TrackWorkQuery();
        query.setOrderId(orderId);
        query.setWorkId(workId);
        ResponseDTO<List<TrackWorkDRO>> listResponseDTO = trackWorkListRemoteService.listTrackByQuery(query);
        if (CollectionUtils.isNotEmpty(listResponseDTO.getData())) {
            List<Long> trackIdList = listResponseDTO.getData().stream().map(TrackWorkDRO::getTrackWorkId).collect(Collectors.toList());
            list.addAll(trackIdList);
        }

        // 加上改派
        OrderWorkRedistributeApplyQuery orderWorkRedistributeApplyQuery = new OrderWorkRedistributeApplyQuery();
        orderWorkRedistributeApplyQuery.setOrderId(orderId);
        orderWorkRedistributeApplyQuery.setWorkId(workId);
        List<OrderWorkRedistributeApply> orderWorkRedistributeApplyList = orderWorkRedistributeApplyService.listByQuery(orderWorkRedistributeApplyQuery);
        if (CollectionUtils.isNotEmpty(orderWorkRedistributeApplyList)) {
            List<Long> cancelApplyIdList = orderWorkRedistributeApplyList.stream().map(OrderWorkRedistributeApply::getRedistributeId).collect(Collectors.toList());
            list.addAll(cancelApplyIdList);
        }

        // 加上取消
        OrderCancelApplyQuery orderCancelApplyQuery = new OrderCancelApplyQuery();
        orderCancelApplyQuery.setOrderId(orderId);
        orderCancelApplyQuery.setWorkId(workId);
        ResponseDTO<List<OrderCancelApplyDRO>> cancelResponseDTO = orderCancelApplyListRemoteService.listCancelApplyByQuery(orderCancelApplyQuery);
        if (CollectionUtils.isNotEmpty(cancelResponseDTO.getData())) {
            List<Long> cancelApplyIdList = cancelResponseDTO.getData().stream().map(OrderCancelApplyDRO::getApplyId).collect(Collectors.toList());
            list.addAll(cancelApplyIdList);
        }

        ResponseDTO<List<OrderRecordDRO>> responseDTO = recordRemoteService.listOrderRecords(list);
        List<OrderRecordDRO> orderRecordDROList = responseDTO.getData();
        if (CollectionUtils.isEmpty(orderRecordDROList)) {
            return null;
        }

        // 查询CCC通话记录
        List<com.zmn.oms.model.vo.work.CallRecordVO> callRecordVOList = Lists.newArrayListWithCapacity(orderRecordDROList.size());
        for (OrderRecordDRO orderRecordDRO : orderRecordDROList) {
            try {
                com.zmn.oms.model.vo.work.CallRecordVO callRecordVO = com.zmn.oms.model.vo.work.CallRecordVO.builder()
                        .callRecordId(String.valueOf(orderRecordDRO.getRecordId()))
                        .type(4)
                        .connect(Objects.equals(true, orderRecordDRO.getConnect()) ? "是" : "否")
                        .answer(Objects.equals(true, orderRecordDRO.getAnswer()) ? "是" : "否")
                        .startTime(orderRecordDRO.getStartTime())
                        .finishTime(orderRecordDRO.getEndTime())
                        .callDuration(DateUtil.getDurationDesc(orderRecordDRO.getPhoneTime()))
                        .callerNo(orderRecordDRO.getCaller())
                        .calledNo(orderRecordDRO.getCallee())
                        .tapeUrl(orderRecordDRO.getRecordFileUrl())
                        .build();
                if (Objects.nonNull(orderRecordDRO.getByeWay())) {
                    callRecordVO.setHangup(CodeAndTextEnum.codeOf(orderRecordDRO.getByeWay(), ByeWayEnum.class).getText());
                }
                callRecordVOList.add(callRecordVO);
            } catch (Exception ex) {
            }
        }
        return callRecordVOList;
    }
}